package com.lmabbe.common.global.redis;

import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.cache.RedisCacheWriter;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.StringRedisSerializer;

import java.io.Serializable;

/**
 * redis配置
 *
 * @author lmabbe
 */
@EnableCaching
@Configuration
public class RedisConfig {

    /**
     * redis操作模板
     *
     * @param connectionFactory :redis链接
     * @return {@link RedisTemplate< String, Serializable>}
     * @date 2022/1/7 8:34 PM
     * @author liming
     */
    @Bean
    public RedisTemplate<String, Object> lmabbeRedisTemplate(LettuceConnectionFactory connectionFactory) {
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        //todo 需要自定义序列化设置
        redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer());
        redisTemplate.setConnectionFactory(connectionFactory);
        return redisTemplate;
    }

    /**
     * redis String 的操作对象
     *
     * @param lmabbeRedisTemplate : redis模板
     * @return {@link ValueOperations< String, Serializable>}
     * @date 2022/1/7 8:33 PM
     * @author liming
     */
    @Bean
    public ValueOperations<String, Object> stringOperation(RedisTemplate<String, Object> lmabbeRedisTemplate) {
        return lmabbeRedisTemplate.opsForValue();
    }

    /**
     * redis key 事件监听
     *
     * @param connectionFactory :
     * @return {@link RedisMessageListenerContainer}
     * @date 2022/1/7 8:20 PM
     * @author liming
     */
    @Bean
    public RedisMessageListenerContainer container(LettuceConnectionFactory connectionFactory) {
        RedisMessageListenerContainer container = new RedisMessageListenerContainer();
        container.setConnectionFactory(connectionFactory);
        return container;
    }

    /**
     * 自定义缓存管理器
     *
     * @param lmabbeRedisTemplate redis操作模板
     * @date 2022/1/7 8:20 PM
     * @author liming
     */
    @Bean
    public RedisCacheManager redisCacheManager(RedisTemplate lmabbeRedisTemplate) {
        RedisCacheWriter redisCacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(lmabbeRedisTemplate.getConnectionFactory());
        RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig()
                .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(lmabbeRedisTemplate.getValueSerializer()));
        return new CustomizerRedisCacheManager(redisCacheWriter, redisCacheConfiguration);
    }
}
